﻿/*
 * Rappelz: Endless Odyssey - The first free open source Rappelz server emulator
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Network;
using System.Data.Common;
using System.Data;
using Rappelz.GameServer.Network.GameClient;
using System.Text.RegularExpressions;

namespace Rappelz.GameServer.Database
{
    /// <summary>
    /// DB_Login
    /// </summary>
    public class DB_Login : IDBProc
    {
        private string m_szCharacterName;
        private TCPConnection m_client;
        private Player m_player;
        private byte m_nPCBangMode;
        private int m_nEventCode;
        private int m_nAge;
        private uint m_nContinuousPlayTime;
        private uint m_nContinuousLogoutTime;
        private int nAccountID;
        private int sid;
        private int[] bindSummon = new int[6];
        private int mainSummon;
        private int subSummon;
        private int remainSummonTime;
        private int pet;
        private int logout_duration;
        private uint[] item_cool_time = new uint[20];
        private long[] beltSlot = new long[6];


        private enum DBFields : int
        {
            Count = 0,
        }
        public DB_Login(TCPConnection client, string szCharacterName, int account_id, Player player, byte nPCBangMode, int nEventCode, int nAge, uint nContinuousPlayTime, uint nContinuousLogoutTime)
        {
            m_client = client;
            sid = -1;
            logout_duration = 0;
            m_player = player;
            m_nPCBangMode = nPCBangMode;
            m_nEventCode = nEventCode;
            m_nAge = nAge;
            m_nContinuousPlayTime = nContinuousPlayTime;
            m_nContinuousLogoutTime = nContinuousLogoutTime;
            nAccountID = account_id;
            m_szCharacterName = szCharacterName;
        }

        BaseObject m_CBObject;

        public void SetCB(BaseObject obj)
        {
            m_CBObject = obj;
        }

        public void RunCB()
        {
            if (m_CBObject != null)
                m_CBObject.onEndQuery();
        }

        public bool onProcess()
        {
// .text:0051690A var_94          = dword ptr -94h
// .text:0051690A var_90          = dword ptr -90h
// .text:0051690A anonymous_0     = byte ptr -88h
            float[] nSummonMP = new float[6];   // -132 -84h
// .text:0051690A _lock           = ArcadiaAutoLock ptr -6Ch
// .text:0051690A db              = dword ptr  4
            int nPlayerHP;                  // 76   4Ch
            int nSummonIdx;                 // 100  64h
            int[] nSummonHP = new int[6];   // 108  6Ch
            int nPlayerMP;                  // 108  6Ch
            Summon pSummon = null;          // 120  78h


// Data           :   ebp Relative, [00000078], Local, Type: unsigned long, t
// Data           :   ebp Relative, [00000078], Local, Type: struct StructSummon *, pSummon
// Data           :   ebp Relative, [FFFFFF98], Local, Type: struct ArcadiaAutoLock, _lock
// Data           :   ebp Relative, [FFFFFF98], Local, Type: struct ArcadiaAutoLock, _lock
// Data           :   ebp Relative, [00000078], Local, Type: class XScopedLock, __scoped_lock
// Data           :   ebp Relative, [FFFFFF98], Local, Type: struct ArcadiaAutoLock, _lock


            bool result = true;
            DbConnection conn = GameDBManager.Instance.CreateConnection();

            if (!readCharacterInfo() || !readItemCoolTime() || !readItemList())
            {
                result = false;
            }

            m_player.CalculateStat();
            if (!readSummonList() || !readPetList() || !readRandomQuestList() || !readQuestList(conn) || !readMaxQuestId() || !readStateInfo(null)
                || !readFavorList() || !readFriendsList() || !readFriendOfsList() || !readDenialsList() || !readDenialOfsList() )
                    result = false;

            if(result)
            {
                m_player.m_StatusFlag |= Creature.StatusFlags.LoginComplete;
                if (m_player.PartyId != 0)
                {
                   if (PartyManager.Instance.GetMemberCount(m_player.m_nPartyId) == 0)
                       m_player.PartyId = 0;
                }
                if (m_player.GuildId > 0 )
                {
                   if (GuildManager.Instance.GetMemberCount(m_player.m_nGuildId) == 0)
                       m_player.GuildId = 0;
                }

                nSummonIdx = 0;
                for(int i = 0; i < 6; ++i)
                {
                    if (bindSummon[nSummonIdx] != 0)
                    {
                        pSummon = m_player.GetSummon(bindSummon[nSummonIdx]);
                        if (pSummon != null)
                        {
                            nSummonHP[nSummonIdx] = pSummon.m_nHP;
                            pSummon.m_cSlotIndex = (byte)nSummonIdx;
                            nSummonMP[nSummonIdx] = pSummon.m_fMP;
                            pSummon.CalculateStat();
                            m_player.m_aBindSummonCard[nSummonIdx] = pSummon.m_item;
                            nSummonIdx++;
                        }
                        else
                        {
                            Globals.Log.Error("Invalid Summon Bind!");
                        }
                    }
                }

                if (mainSummon != 0)
                {
                    pSummon = m_player.GetSummon(mainSummon);
                    if (pSummon != null)
                    {
                        m_player.m_pMainSummon = pSummon;
                        if(subSummon != 0)
                        {
                            pSummon = m_player.GetSummon(subSummon);
                            if (pSummon != null)
                            {
                                m_player.m_pSubSummon = pSummon;
                                m_player.m_nNextUnSummonTime = (uint)remainSummonTime + Globals.GetArTime();
                            }
                        }
                    }
                }
//                 if (pet != 0)
//                     v22 = m_player.GetPet(pet);
//                 else
//                     v22 = 0;
//                 if (v22 && v22->m_bNameChanged )
//                     m_player.m_pSummonedPet = v22;

                if (readEquipItemList(conn) )
                {
                    m_player.CalculateStat();
                    setBeltSlotInfo();
                    m_player.CalculateStat();
//                     m_player.SetHP((v2 + 76));
//                     m_player.SetMP((v2 + 108));

                    for(int i = 0; i < 6; ++i)
                    {
                        Creature cr = m_player.GetSummonAt(i);
                        if (cr != null)
                        {
                            cr.CalculateStat();
//                             cr.SetHP(*(_DWORD *)(v2 + 4 * i - 108));
//                             cr.SetMP(*(_DWORD *)(v2 + 4 * i - 132));
                        }
                    }
                    m_player.m_nWarpEndTime = Globals.GetArTime();
                    m_player.m_StatusFlag |= Creature.StatusFlags.Invincible;

//                     v25 = GetArTime();
//                     *(_DWORD *)(v2 + 120) = v25;
                    if (GameRule.bAutoOpen)
                    {
                        if (m_player.m_bAutoUsed || Player.IsAutoAccount(m_player.AccountID))
                        {
                            if (GameRule.bUseAutoJail)
                            {
//                                v51 = RappelzServer.Instance.LockObjectWithVisibleRange((ArcadiaLock *)(v2 + 76), m_player);
//                                ArcadiaAutoLock::ArcadiaAutoLock((ArcadiaAutoLock *)(v2 - 104), v51);
                                m_player.m_bAutoUsed = true;

//                                m_player.AddState(0, NEMESIS_FOR_AUTO, 0, 11, v54, v52 + 86400000, 0, 0, "");
                                m_player.Save(true);

                                Globals.Log.Info("Checked Auto Account: {0}", m_player.GetHandle());
//                                ArcadiaAutoLock::_ArcadiaAutoLock((ArcadiaAutoLock *)(v2 - 104));
                            }
                            ServerLog.Log(3200, m_player.AccountID,0,0,0,0,0,0,0,0,2,0, m_player.AccountName,"","","");
                        }
                    }
                    else
                    {
//                        v28 = RappelzServer.Instance.LockObjectWithVisibleRange((ArcadiaLock *)(v2 + 76),m_player);
//                        ArcadiaAutoLock::ArcadiaAutoLock((ArcadiaAutoLock *)(v2 - 104),v28);

                        if (GameRule.bUseAutoJail)
                        {
                            m_player.m_bAutoUsed = true;
//                            m_player.AddState(0, NEMESIS_FOR_AUTO, 0, 11, *(_DWORD *)(v2 + 120), *(_DWORD *)(v2 + 120) + 86400000, 0, 0, "");
                            m_player.Save(true);

                            Globals.Log.Info("Checked Auto Open: {0}", m_player.GetHandle());
                            Player.AddToAutoAccountList(m_player.AccountID);
                        }
                        ServerLog.Log(3200, m_player.AccountID,0,0,0,0,0,0,0,0,1,0, m_player.AccountName,"","","");
//                        ArcadiaAutoLock::_ArcadiaAutoLock((ArcadiaAutoLock *)(v2 - 104));
                    }

                    Messages.SendLoginResult(m_client, m_player, "");
                    m_player.ChangeLocation(m_player.mv.x, m_player.mv.y, false, true);
                    m_player.m_nEventCode = m_nEventCode;
                    m_player.m_nAge = m_nAge;

                    ConnectionTag tag = m_client.Tag;
                    if (tag != null)
                    {
                        lock(tag)
                        {
    //                        v75 = RappelzServer.Instance.LockObjectWithVisibleRange((ArcadiaLock *)(v2 + 108), m_player);
    //                        ArcadiaAutoLock::ArcadiaAutoLock((ArcadiaAutoLock *)(v2 - 104),v75);
                            m_player.SetContinuousPlayTime(m_player.m_nContinuousPlayTime);
                            m_player.m_nContinuousLogoutTime = m_nContinuousLogoutTime;
    //                        ArcadiaAutoLock::_ArcadiaAutoLock((ArcadiaAutoLock *)(v2 - 104));

                        }
                    }
                    if (GameRule.bIsCashUsableServer)
                    {
                        m_player.DBQuery(new DB_GetCommercialStorageInfo(m_player,true));
                    }
                    else
                    {
                        if (GameRule.bIsServiceServer || (m_player.m_bUsingTent) || m_player.m_bIsGaiaMember)
                        {
                            m_player.AddStamina(logout_duration * m_player.GetStaminaRegenRate());
                        }
                        ServerLog.Log(2101,m_player.AccountID,0,0,0,0,m_player.m_nStamina, m_player.m_nGold,m_player.m_layer,(long)m_player.mv.x,(long)m_player.mv.y,0,m_player.AccountName,"","","");

                        ulong ul_ip = (ulong)((double)m_player.m_fImmoralPoint / 10000.0);
                        ServerLog.Log(2103, m_player.AccountID, 0, 0, 0, 0, 0, m_player.m_nGold, m_player.m_nStorageGold, m_player.m_nChaos, (long)ul_ip, m_player.m_nEXP, m_player.AccountName, "", "", "");
                    }
                    result = true;
                }
                else
                {
                    Messages.SendLoginResult(m_client, m_player, "Login error");
                    m_player.LogoutNow(3);
                    result = false;
                }

            }
            return result;
        }

        private bool readCharacterInfo()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();
            cmd.Connection = conn;

            cmd.CommandText = "smp_login_character";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter out_sid = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SID", DbType.Int32);
            DbParameter out_account = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_ACCOUNT", DbType.AnsiString, 60);
            DbParameter out_permisson = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PERMISSION", DbType.Int32);
            DbParameter out_party_sid = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PARTY_SID", DbType.Int32);
            DbParameter out_guild_sid = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_GUILD_SID", DbType.Int32);
            DbParameter out_prev_guild_sid = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PREV_GUILD_SID", DbType.Int32);
            DbParameter out_guild_permission = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_GUILD_PERMISSION", DbType.Byte);
            DbParameter out_x = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_X", DbType.Int32);
            DbParameter out_y = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_Y", DbType.Int32);
            DbParameter out_z = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_Z", DbType.Int32);
            DbParameter out_layer = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_LAYER", DbType.Int32);
            DbParameter out_race = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_RACE", DbType.Int32);
            DbParameter out_sex = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SEX", DbType.Int32);
            DbParameter out_lv = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_LV", DbType.Int32);
            DbParameter out_max_reached_level = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MAX_REACHED_LEVEL", DbType.Int32);
            DbParameter out_exp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_EXP", DbType.Int64);
            DbParameter out_last_decreased_exp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_LAST_DECREASED_EXP", DbType.Int64);
            DbParameter out_hp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HP", DbType.Int32);
            DbParameter out_mp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MP", DbType.Int32);
            DbParameter out_stamina = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_STAMINA", DbType.Int32);
            DbParameter out_havoc = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HAVOC", DbType.Int32);
            DbParameter out_job = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JOB", DbType.Int32);
            DbParameter out_job_depth = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JOB_DEPTH", DbType.Int32);
            DbParameter out_jlv = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JLV", DbType.Int32);
            DbParameter out_jp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JP", DbType.Int64);
            DbParameter out_total_jp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_TOTAL_JP", DbType.Int64);
            DbParameter out_tp = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_TALENT_POINT", DbType.Int32);
            DbParameter out_job_0 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JOB_0", DbType.Int32);
            DbParameter out_job_1 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JOB_1", DbType.Int32);
            DbParameter out_job_2 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JOB_2", DbType.Int32);
            DbParameter out_jlv_0 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JLV_0", DbType.Int32);
            DbParameter out_jlv_1 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JLV_1", DbType.Int32);
            DbParameter out_jlv_2 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_JLV_2", DbType.Int32);
            DbParameter out_ip = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_IP", DbType.Decimal);
            DbParameter out_cha = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_CHA", DbType.Int32);
            DbParameter out_pkc = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PKC", DbType.Int32);
            DbParameter out_dkc = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_DKC", DbType.Int32);
            DbParameter out_huntaholic = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HUNTAHOLIC_POINT", DbType.Int32);
            DbParameter out_huntaholic_enter_count = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HUNTAHOLIC_ENTER_COUNT", DbType.Int32);
            DbParameter out_ethereal_stone_durability = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_ETHEREAL_STONE_DURABILITY", DbType.Int32);
            DbParameter out_summon_0 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUMMON_0", DbType.Int32);
            DbParameter out_summon_1 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUMMON_1", DbType.Int32);
            DbParameter out_summon_2 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUMMON_2", DbType.Int32);
            DbParameter out_summon_3 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUMMON_3", DbType.Int32);
            DbParameter out_summon_4 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUMMON_4", DbType.Int32);
            DbParameter out_summon_5 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUMMON_5", DbType.Int32);
            DbParameter out_skin_color = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SKIN_COLOR", DbType.Int32);
            DbParameter out_model_00 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MODEL_00", DbType.Int32);
            DbParameter out_model_01 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MODEL_01", DbType.Int32);
            DbParameter out_model_02 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MODEL_02", DbType.Int32);
            DbParameter out_model_03 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MODEL_03", DbType.Int32);
            DbParameter out_model_04 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MODEL_04", DbType.Int32);
            DbParameter OUT_HAIR_COLOR_INDEX = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HAIR_COLOR_INDEX", DbType.Int32);
            DbParameter OUT_HAIR_COLOR_RGB = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HAIR_COLOR_RGB", DbType.Int32);
            DbParameter OUT_HIDE_EQUIP_FLAG = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_HIDE_EQUIP_FLAG", DbType.Int32);
            DbParameter OUT_TEXTURE_ID = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_TEXTURE_ID", DbType.Int32);

            DbParameter out_belt_0 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_BELT_0", DbType.Int64);
            DbParameter out_belt_1 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_BELT_1", DbType.Int64);
            DbParameter out_belt_2 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_BELT_2", DbType.Int64);
            DbParameter out_belt_3 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_BELT_3", DbType.Int64);
            DbParameter out_belt_4 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_BELT_4", DbType.Int64);
            DbParameter out_belt_5 = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_BELT_5", DbType.Int64);
            DbParameter out_gold = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_GOLD", DbType.Int64);
            DbParameter out_chaos = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_CHAOS", DbType.Int32);
            DbParameter out_flag_list = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_FLAG_LIST", DbType.AnsiString, 4000);
            DbParameter out_client_info = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_CLIENT_INFO", DbType.AnsiString, 4096);
            DbParameter out_login_count = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_LOGIN_COUNT", DbType.Int32);
            DbParameter out_main_summon = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_MAIN_SUMMON", DbType.Int32);
            DbParameter out_sub_summon = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_SUB_SUMMON", DbType.Int32);
            DbParameter out_remain_summon_time = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_REMAIN_SUMMON_TIME", DbType.Int32);
            DbParameter out_pet = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PET", DbType.Int32);
            DbParameter out_remain_chat_block_time = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_REMAIN_CHAT_BLOCK_TIME", DbType.Int32);
            DbParameter out_adv_chat_count = GameDBManager.Instance.CreateOutParameter(cmd, "ADV_CHAT_COUNT", DbType.Int32);
            DbParameter out_logout_duration = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_LOGOUT_DURATION", DbType.Int32);
            DbParameter out_name_changed = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_NAME_CHANGED", DbType.Int32);
            DbParameter out_auto_used = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_AUTO_USED", DbType.Int32);
            DbParameter out_guild_block_time = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_GUILD_BLOCK_TIME", DbType.DateTime);
            DbParameter out_pkmode = GameDBManager.Instance.CreateOutParameter(cmd, "OUT_PKMODE", DbType.Byte);
            DbParameter in_name = GameDBManager.Instance.CreateInParameter(cmd, "IN_NAME", DbType.String, this.m_szCharacterName);
            DbParameter in_account_id = GameDBManager.Instance.CreateInParameter(cmd, "IN_ACCOUNT_ID", DbType.Int32, this.nAccountID);

            conn.Open();
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (System.Exception ex)
            {
                Globals.Log.Error("DB_Login.readCharacterInfo Exception: {0}", ex);
            }

            this.sid = (int)out_sid.Value;
            if(sid <= 0)
            {
                Globals.Log.Error("Character not found~! ({0})", this.m_szCharacterName);
                return false;
            }

//            this.m_player.SetName(*(StructPlayer **)(v499 + 356), (const char *)pEnd);
            this.m_player.Name = this.m_szCharacterName;
            this.m_player.SID = this.sid;
            //*(_DWORD *)(v499 + 412) = this.m_player.m_nUID;
            this.m_player.AccountName = (string) out_account.Value;
            //*(_DWORD *)&strKey.baseclass_0.___u0.baseclass_0.baseclass_0.dummy[0] = this.m_player.m_szAccountName;
            int x = (int)out_x.Value;
            int y = (int)out_y.Value;

            //v550 = *(ArObject **)(v499 + 356);
            this.m_player.SetCurrentXY((float)x,(float)y);
            this.m_player.m_layer = (byte) (int) out_layer.Value;
            this.m_player.m_nRace = (int) out_race.Value;

//            string[] stringSeparators = new string[] {"\r\n"};

            string flaglist = (string) out_flag_list.Value;
            string[] flaga1 = Regex.Split(flaglist, "\n"); //flaglist.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);
            foreach (string s in flaga1)
            {
                string[] flag2 = s.Split(':');
                if(flag2 != null && flag2.Length == 2)
                {
                    m_player.SetFlag(flag2[0], flag2[1]);
                }
            }

            this.m_player.PartyId = (int) out_party_sid.Value;
            this.m_player.GuildId = (int) out_guild_sid.Value;
            this.m_player.PrevGuildId = (int) out_prev_guild_sid.Value;
            this.m_player.m_nSex = (int) out_sex.Value;
            this.m_player.m_nLevel = (int) out_lv.Value;
            this.m_player.m_nMaxReachedLevel = (int) out_max_reached_level.Value;
            this.m_player.m_nEXP = (long) out_exp.Value;
            this.m_player.m_nLastDecreasedEXP = (long) out_last_decreased_exp.Value;
            this.m_player.m_nHP = (int) out_hp.Value;
            this.m_player.m_fMP = (float)(int)out_mp.Value;
            this.m_player.m_nStamina = (int) out_stamina.Value;
            this.m_player.m_nJobLevel = (int) out_jlv.Value;
            this.m_player.m_nPrevJobId[0] = (int) out_job_0.Value;
            this.m_player.m_nPrevJobId[1] = (int) out_job_1.Value;
            this.m_player.m_nPrevJobId[2] = (int) out_job_2.Value;
            this.m_player.m_nPrevJobLevel[0] = (int) out_jlv_0.Value;
            this.m_player.m_nPrevJobLevel[1] = (int) out_jlv_1.Value;
            this.m_player.m_nPrevJobLevel[2] = (int) out_jlv_2.Value;
            this.m_player.m_nJobPoint = (long) out_jp.Value;
            this.m_player.m_nTotalJobPoint = (long) out_total_jp.Value;
            // need to parse this one still
            Decimal immoralitypoints = (Decimal) out_ip.Value;
            this.m_player.m_nCharisma = (int) out_cha.Value;
            this.m_player.m_nPKC = (int) out_pkc.Value;
            this.m_player.m_nDKC = (int) out_dkc.Value;
            this.m_player.SetHuntaholicPoint((int) out_huntaholic.Value);
            this.m_player.m_nJob = (int) out_job.Value;
            this.m_player.m_nPermission = (int) out_permisson.Value;
            this.m_player.m_nGold = (long) out_gold.Value;
            this.m_player.m_nChaos = (int) out_chaos.Value;
            this.m_player.m_nSkinColor = (uint) (int) out_skin_color.Value;
            this.m_player.m_nLoginCount = (int) out_login_count.Value;
            this.m_player.m_nBaseModelId[0] = (int) out_model_00.Value;
            this.m_player.m_nBaseModelId[1] = (int) out_model_01.Value;
            this.m_player.m_nBaseModelId[2] = (int) out_model_02.Value;
            this.m_player.m_nBaseModelId[3] = (int) out_model_03.Value;
            this.m_player.m_nBaseModelId[4] = (int) out_model_04.Value;
            this.m_player.m_HairDye = (int)OUT_HAIR_COLOR_INDEX.Value;
            this.m_player.m_HairCut = (int)OUT_HAIR_COLOR_RGB.Value;
            this.m_player.m_Unk1 = (int)OUT_HIDE_EQUIP_FLAG.Value;
            this.m_player.m_FaceScars = (int)OUT_TEXTURE_ID.Value;
//            this.m_player.m_nGuildRank = (int)out_guild_rank.Value;
//            this.m_player.m_strGuildMemo = (string)out_memo.Value;



            this.m_player.m_strClientInfo = (string) out_client_info.Value;
            this.m_player.m_nChatBlockTime = 0;

            // TODO: need to parse this one still
//            this.m_player.m_nChatBlockTime = ((int) out_remain_chat_block_time.Value) + ArTime() / 100;
            this.m_player.m_nAdvChatCount = (int) out_adv_chat_count.Value;
            this.m_player.m_nNameChanged = (int) out_name_changed.Value;
            this.m_player.m_nTP = (int)out_tp.Value;
            this.m_player.m_bAutoUsed = ((int)out_auto_used.Value) != 0;
//            this.m_player.m_tGuildBlockTime = (long) out_guild_block_time.Value;
            this.m_player.m_bIsPK = ((byte) out_pkmode.Value) != 0;
            this.m_player.m_nLogoutDuration = (int) out_logout_duration.Value;
            this.logout_duration = this.m_player.m_nLogoutDuration;

            this.bindSummon[0] = (int) out_summon_0.Value;
            this.bindSummon[1] = (int) out_summon_1.Value;
            this.bindSummon[2] = (int) out_summon_2.Value;
            this.bindSummon[3] = (int) out_summon_3.Value;
            this.bindSummon[4] = (int) out_summon_4.Value;
            this.bindSummon[5] = (int) out_summon_5.Value;

            this.beltSlot[0] = (long) out_belt_0.Value;
            this.beltSlot[1] = (long) out_belt_1.Value;
            this.beltSlot[2] = (long) out_belt_2.Value;
            this.beltSlot[3] = (long) out_belt_3.Value;
            this.beltSlot[4] = (long) out_belt_4.Value;
            this.beltSlot[5] = (long) out_belt_5.Value;

            this.mainSummon = (int) out_main_summon.Value;
            this.subSummon = (int) out_sub_summon.Value;
            this.remainSummonTime = (int) out_remain_summon_time.Value;
            this.pet = (int) out_pet.Value;

            conn.Close();
            ArPosition pos = null;

            int hunt_id = HuntaholicManager.Instance.GetHuntaholicID(this.m_player.mv);
            if (hunt_id != 0)
            {
                if (!HuntaholicManager.Instance.IsHuntaholicDungeon(this.m_player.mv))
                {
                    if (this.m_player.PartyId == 0 || HuntaholicManager.Instance.LeaveInstanceDungeon(hunt_id, m_player) == 0)
                    {
                        m_player.m_layer = HuntaholicManager.Instance.GetProperLobbyLayer(hunt_id, m_player.GetLevel());
                    }
                    else 
                    {
                        if (PartyManager.Instance.IsLeader(m_player.PartyId, m_player.AccountName))
                        {
                            ServerLog.Log(3401, m_player.GetAccountID(), m_player.GetSID(), (long)m_player.mv.x, (long)m_player.mv.y, (long)m_player.mv.z, m_player.m_layer, 10, 0, 0, 0, 0, m_player.GetAccountName(), m_player.GetName(), "", "");

                            Messages.BroadcastPartyDestroy(this.m_player.PartyId);
                            PartyManager.Instance.DestroyParty(this.m_player.PartyId);
                            m_player.PartyId = 0;
                            m_player.m_layer = HuntaholicManager.Instance.GetProperLobbyLayer(hunt_id, m_player.GetLevel());
                        }
                        else
                        {
                            Messages.PrintfPartyChatMessage(100, m_player.PartyId, "LEAVE|%s|", m_player.GetName());
                        }
                        PartyManager.Instance.LeaveParty(m_player.PartyId, m_player.GetName());
                        m_player.PartyId = 0;
                        m_player.m_layer = HuntaholicManager.Instance.GetProperLobbyLayer(hunt_id, m_player.GetLevel());
                    }
                }
                else
                {
                    // must be in the lobby
                    if (m_player.PartyId != 0 && HuntaholicManager.Instance.QuitHunting(hunt_id, m_player, false,-1) != 0)
                    {
                        pos = HuntaholicManager.Instance.GetLobbyPosition(hunt_id);
                        m_player.SetCurrentXY(pos.x, pos.y);
                        m_player.m_layer = HuntaholicManager.Instance.GetProperLobbyLayer(hunt_id, m_player.GetLevel());
                    }
                    else 
                    {
                        if (PartyManager.Instance.IsLeader(m_player.PartyId, m_player.AccountName))
                        {
                            ServerLog.Log(3401, m_player.GetAccountID(), m_player.GetSID(), (long)m_player.mv.x, (long)m_player.mv.y, (long)m_player.mv.z, m_player.m_layer, 10, 0, 0, 0, 0, m_player.GetAccountName(), m_player.GetName(), "", "");
                            Messages.BroadcastPartyDestroy(this.m_player.PartyId);
                            PartyManager.Instance.DestroyParty(this.m_player.PartyId);
                            m_player.PartyId = 0;
                            m_player.m_layer = HuntaholicManager.Instance.GetProperLobbyLayer(hunt_id, m_player.GetLevel());
                        }
                        else
                        {
                            Messages.PrintfPartyChatMessage(100, m_player.PartyId, "LEAVE|%s|", m_player.GetName());
                        }
                        PartyManager.Instance.LeaveParty(m_player.PartyId, m_player.GetName());
                        m_player.PartyId = 0;
                        m_player.m_layer = HuntaholicManager.Instance.GetProperLobbyLayer(hunt_id, m_player.GetLevel());
                    }
                }
            }

            int dungeon_id = 0;
            if (m_player.m_layer != 0)
                dungeon_id = DungeonManager.Instance.GetDungeonID( m_player.mv.x, m_player.mv.y);

            if (dungeon_id != 0)
            {
                pos = null;
                if ((this.logout_duration * 60 <= 3600) && (m_player.m_layer != 0xff) && (m_player.PartyId != 0))
                {
                    int atk_guild_id = PartyManager.Instance.GetAttackTeamGuildID(m_player.PartyId);
                    if (atk_guild_id != 0)
                    {
                        if (m_player.m_layer == 1)
                        {
                            if (DungeonManager.Instance.IsEnterableSiegeDungeon(dungeon_id, atk_guild_id))
                            {
                                int test_id = m_player.GuildId;
                                int guild_alliance_id = GuildManager.Instance.GetAllianceID(m_player.GuildId);
                                if ( guild_alliance_id != 0 )
                                {
                                    test_id = GuildManager.Instance.GetAllianceLeaderGuildID(guild_alliance_id);
                                }
                                int own_id = DungeonManager.Instance.GetOwnGuildID(dungeon_id);
                                if ( test_id == own_id )
                                {
                                    pos = DungeonManager.Instance.GetSiegeDefencePosition(dungeon_id);
                                }
                                else
                                {
                                    pos = DungeonManager.Instance.GetSiegeStartPosition(dungeon_id);
                                }
                                m_player.SetCurrentXY(pos.x, pos.y);
                            }
                        }
                        else
                        {
                            if (DungeonManager.Instance.GetRaidDungeonLayer(dungeon_id, atk_guild_id) == m_player.m_layer)
                            {
                                pos = DungeonManager.Instance.GetRaidStartPosition(dungeon_id);
                                m_player.SetCurrentXY(pos.x, pos.y);
                            }
                        }
                    }
                }
                if(pos == null)
                {
                    pos = DungeonManager.Instance.GetRaidStartPosition(dungeon_id);
                    m_player.SetCurrentXY(pos.x, pos.y);
                    m_player.m_layer = 0;
                }
            }
            else
            {
                byte clayer = ChannelManager.GetProperLayer(m_player.mv.x, m_player.mv.y);
                if (this.logout_duration * 60 > 3600 ||  clayer == 0)
                {
                    m_player.m_layer = clayer;
                }
            }

            if (m_player.m_nLevel == 0)
            {
                m_player.m_nLevel = 1;
                m_player.m_nMaxReachedLevel = 1;
                m_player.m_nJobLevel = 1;
                m_player.m_nHP = m_player.m_nMaxHP;
                m_player.m_fMP = m_player.m_nMaxMP;
            }
            readCreatureSkillList(m_player);
            return true;
        }


        private bool readItemCoolTime()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_item_cool_time";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter ind_uid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_UID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReader datareader = cmd.ExecuteReader();
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(datareader);

                if (dr.Read())
                {
                    for(int i = 0; i < 40; ++i)
                    {
                        m_player.m_nItemCoolTime[i] = (uint) dr.GetInt32(i);
                        if(m_player.m_nItemCoolTime[i] <= this.logout_duration)
                            m_player.m_nItemCoolTime[i] = 0;
                    }
                }



            }
            catch (System.Exception ex)
            {
            	Globals.Log.Error("Error in DB_Login.readItemCoolTime: {0}", ex);
            }

            conn.Close();

            return true;
        }

        private bool readItemList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_item_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter ind_uid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                int unInv = 0;
                int Inv = 0;

                while (dr.Read())
                {
                    long sid = dr.GetInt64(0);
                    int owner_id = dr.GetInt32(1);
                    int account_id = dr.GetInt32(2);
                    int flag = dr.GetInt32(3);
                    int code = dr.GetInt32(4);
                    int idx = dr.GetInt32(5);
                    long cnt = dr.GetInt64(6);
                    int level = dr.GetInt32(7);
                    int enhance = dr.GetInt32(8);
                    int dura = dr.GetInt32(9);
                    int endurance = dr.GetInt32(10);
                    ItemInstance.GenerateCode gcode = (ItemInstance.GenerateCode) dr.GetInt32(11);
                    int wear_info = dr.GetInt32(12);
                    int socket_0 = dr.GetInt32(13);
                    int socket_1 = dr.GetInt32(14);

                    int socket_2 = dr.GetInt32(15);
                    int socket_3 = dr.GetInt32(16);
                    int remain_time = dr.GetInt32(17);
                    Elemental.Type elemental_effect_type = (Elemental.Type) dr.GetByte(18);
                    DateTime elemental_effect_expire_time = dr.GetDateTime(19);
                    long elem = (long)(elemental_effect_expire_time - Globals.StartOfEpoch).TotalMilliseconds;
//             *(_DWORD *)(v2 - 460) = ATL::COleDateTime::GetYear((ATL::COleDateTime *)(v2 + 76)) - 1900;
//             *(_DWORD *)(v2 - 464) = ATL::COleDateTime::GetMonth((ATL::COleDateTime *)(v2 + 76)) - 1;
//             *(_DWORD *)(v2 - 468) = ATL::COleDateTime::GetDay((ATL::COleDateTime *)(v2 + 76));
//             *(_DWORD *)(v2 - 472) = ATL::COleDateTime::GetHour((ATL::COleDateTime *)(v2 + 76));
//             *(_DWORD *)(v2 - 476) = ATL::COleDateTime::GetMinute((ATL::COleDateTime *)(v2 + 76));
//             *(_DWORD *)(v2 - 480) = ATL::COleDateTime::GetSecond((ATL::COleDateTime *)(v2 + 76));

                    int elemental_effect_attack_point = dr.GetInt32(20);
                    int elemental_effect_magic_point = dr.GetInt32(21);

                    Item item = Item.AllocItem(sid, code, cnt, gcode, level, dura, enhance, flag, socket_0, socket_1, socket_2, socket_3, remain_time, elemental_effect_type, elem, elemental_effect_attack_point, elemental_effect_magic_point);
                    item.m_Instance.Flag &= 0xDFFFFFFF;
                    item.SetCurrentEndurance(endurance);

                    if (code != 0)
                    {
                        item.m_Instance.nWearInfo = ItemBase.ItemWearType.WearNone;
                        item.m_unInventoryIndex = (uint)unInv;
                        unInv++;
                        Inv++;
                        item.m_Instance.nIdx = Inv;
                        item.m_bIsNeedUpdateToDB = idx != Inv;
                        Item citem = m_player.PushItem(item, item.m_Instance.nCount, false);
                        if (item.IsJoinable() && !ReferenceEquals(citem,item))
                        {
                            item.SetOwnerInfo(0, 0, 0);
                            item.DBQuery(new DB_UpdateItemOwner(item));
                            Item.PendFreeItem(item);

                            citem.DBQuery(new DB_UpdateItem(citem));
                            Inv--;
                        }
                    }
                    else
                    {
                        item.SetOwnerInfo(0, 0, 0);
                        item.DBQuery(new DB_UpdateItemOwner(item));
                        Item.PendFreeItem(item);
                    }
                }
            }
            catch (System.Exception ex)
            {
            	Globals.Log.Error("Error in DB_Login.readItemList: {0}", ex);
            }
            conn.Close();
            return true;
        }
        

        private bool readSummonList()
        {

            bool result = false;
            if (m_player.m_nLogoutTime != 0)
            {
                result = false;
            }
            else
            {
                DbConnection conn = GameDBManager.Instance.CreateConnection();
                DbCommand cmd = conn.CreateCommand();

                cmd.CommandText = "smp_read_summon_list";
                cmd.CommandType = CommandType.StoredProcedure;

                DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);
                if(conn.State != ConnectionState.Open)
                    conn.Open();
                try
                {
                    DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                    while (dr.Read())
                    {
                        int sid = dr.GetInt32(0);
                        int code = dr.GetInt32(1); // code
                        long card_uid = dr.GetInt64(2);
                        long exp = dr.GetInt64(3);
                        long last_decreased_exp = dr.GetInt64(4);
                        int jp = dr.GetInt32(5);
                        string name = dr.GetString(6);
                        int transform = dr.GetInt32(7);
                        int lv = dr.GetInt32(8);
                        int jlv = dr.GetInt32(9);
                        int max_level = dr.GetInt32(10);
                        int fp = dr.GetInt32(11);
                        int sp = dr.GetInt32(12);
                        int hp = dr.GetInt32(13);
                        int mp = dr.GetInt32(14);
                        int prev_id_01 = dr.GetInt32(15);
                        int prev_id_02 = dr.GetInt32(16);
                        int prev_level_01 = dr.GetInt32(17);
                        int prev_level_02 = dr.GetInt32(18);

                        Summon summon = Summon.AllocSummon(m_player, (uint) code);
                        summon.SetEXP(exp);
                        summon.SetLevel(lv);
                        summon.SetJobLevel(jlv); // possibly lv instead
                        summon.SetMaxReachedLevel(max_level);
                        summon.m_nSID = sid;
                        summon.SetJP(jp);
                        summon.SetName(name);
                        summon.SetCurrentXY(m_player.mv.x, m_player.mv.y);
                        summon.SetPrevJobId(0,prev_id_01);
                        summon.SetPrevJobId(1,prev_id_02);
                        summon.SetPrevJobLevel(0,prev_level_01);
                        summon.SetPrevJobLevel(1,prev_level_02);
                        summon.m_nLastDecreasedEXP = last_decreased_exp;
                        Item card = m_player.FindItemBySID(card_uid);
                        if (card != null)
                        {
                            summon.m_item = card;
                            card.m_pSummon = summon;
                            card.m_Instance.Socket[0] = summon.m_nSID;
                            card.m_bIsNeedUpdateToDB = true;
                            m_player.AddSummon(summon, false);
                            readCreatureSkillList(summon);
                            readStateInfo(summon);
                            summon.SetLoginComplete();
                            summon.m_nSP = sp;
                            summon.m_nHP = hp;
                            summon.m_fMP = mp;
                        }
                        else
                        {
                            summon.m_nAccountId = 0;
                            summon.m_master = null;
                            summon.DBQuery(new DB_UpdateSummon(summon, false));
                            RappelzServer.Instance.DeleteObject(summon);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    Globals.Log.Error("Error in DB_Login.readSummonList: {0}", ex);
                }
                conn.Close();
                result = true;
            }
            return result;
        }

        private bool readPetList()
        {
            if(m_player.m_nLogoutTime != 0)
                return false;

            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_pet_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    int sid = dr.GetInt32(0);
                    int code = dr.GetInt32(1); // code
                    string name = dr.GetString(2);
                    int name_changed = dr.GetInt32(3);
                    long cage_uid = dr.GetInt64(4);
                    uint cool_time_01 = (uint) dr.GetInt32(5);

                    Pet pet = Pet.AllocPet(m_player, (uint)code);
                    pet.m_nSID = sid;
                    pet.SetName(name);
                    pet.m_bNameChanged = name_changed != 0;
                    Skill skill = pet.GetSkill(6907);
                    skill.SetRemainCoolTime(100 * cool_time_01);
                    pet.SetCurrentXY(m_player.mv.x, m_player.mv.y);
                    Item cage = m_player.FindItemBySID(cage_uid);

                    if (cage != null )
                    {
                        pet.m_item = cage;
                        cage.m_pPet = pet;
                        m_player.AddPet(pet, false);
                        pet.SetLoginComplete();
                        pet.m_nHP = 100;
                        pet.m_fMP = 100;
                    }
                    else
                    {
                        pet.m_master = null;
                        pet.DBQuery(new DB_UpdatePet(pet));
                        RappelzServer.Instance.DeleteObject(pet);
                    }
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readPetList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readRandomQuestList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_random_quest_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    int[] keys = new int[3];
                    int[] values = new int[3];
                    int code = dr.GetInt32(0);
                    keys[0] = dr.GetInt32(1);
                    keys[1] = dr.GetInt32(2);
                    keys[2] = dr.GetInt32(3);
                    values[0] = dr.GetInt32(4);
                    values[1] = dr.GetInt32(5);
                    values[2] = dr.GetInt32(6);
                    bool is_dropped = dr.GetByte(7) != 0;

                    m_player.m_QuestManager.AddRandomQuestInfo(code, keys, values, is_dropped);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readRandomQuestList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readQuestList(DbConnection conn)
        {
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_quest_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    int[] status = new int[6];

                    int off = 0;
                    int owner_id = 0;// dr.GetInt32(off++);
                    int id = dr.GetInt32(off++);
                    int code = dr.GetInt32(off++);
                    int start_id = dr.GetInt32(off++);
                    status[0] = dr.GetInt32(off++);
                    status[1] = dr.GetInt32(off++);
                    status[2] = dr.GetInt32(off++);
                    status[3] = dr.GetInt32(off++);
                    status[4] = dr.GetInt32(off++);
                    status[5] = dr.GetInt32(off++);
                    int time_remaining = dr.GetInt32(off++);
                    int progress = dr.GetInt32(off++);



//                     if ( v125 )
//                         v126 = (Quest.QuestEventHandler *)(v125 + 4072);
//                     else
//                         v126 = 0;
                    Quest quest = Quest.AllocQuest(m_player, id,code, status, (QuestInstance.QuestProgress) progress, start_id);

                    if (!m_player.m_QuestManager.AddQuest(quest))
                        quest.FreeQuest();
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readQuestList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readMaxQuestId()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_max_quest_id";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());
                if(dr.Read())
                {
                    int max_id = dr.GetInt32(0);
                    m_player.m_QuestManager.SetMaxQuestID(max_id);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readMaxQuestId Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readStateInfo(Summon summon)
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_state_list";
            cmd.CommandType = CommandType.StoredProcedure;

            int summon_id = 0;
            if(summon != null)
                summon_id = summon.m_nSID;
            DbParameter in_owner_uid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.Int32, m_player.m_nUID);
            DbParameter in_summon_uid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SUMMON_ID", DbType.Int32, summon_id);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    ushort[] level = new ushort[3];
                    uint[] duration = new uint[3];
                    int[] remain_time = new int[3];
                    int[] base_damage = new int[3];

                    for (int i = 0; i < 3; ++i)
                    {
                        level[i] = 0;
                        duration[i] = 0;
                        remain_time[i] = 0;
                        base_damage[i] = 0;
                    }

                    int off = 0;
                    int sid = dr.GetInt32(off++);
                    State.StateCode code = (State.StateCode)dr.GetInt32(off++);
                    level[0] = (ushort)dr.GetInt64(off++);
//                    level[1] = (ushort)dr.GetInt32(off++);
//                    level[2] = (ushort)dr.GetInt32(off++);
                    duration[0] = (uint)dr.GetInt32(off++);
//                    duration[1] = (uint)dr.GetInt32(off++);
//                    duration[2] = (uint)dr.GetInt32(off++);
                    remain_time[0] = dr.GetInt32(off++);
//                    remain_time[1] = dr.GetInt32(off++);
//                    remain_time[2] = dr.GetInt32(off++);
                    base_damage[0] = dr.GetInt32(off++);
//                    base_damage[1] = dr.GetInt32(off++);
//                    base_damage[2] = dr.GetInt32(off++);
                    int remain_fire_time = dr.GetInt32(off++);
                    int state_value = dr.GetInt32(off++);
                    string state_string_value = dr.GetString(off++);
                    int enable = dr.GetInt32(off++);
                    uint handle = 0;

                    State state = new State();

                    Creature cr = null;

                    if (summon != null)
                    {
                        cr = summon;
                        summon.m_vStateIDList.Add(sid);
                    }
                    else
                    {
                        cr = m_player;
                        m_player.m_vStateIDList.Add(sid);
                    }

                    StateInfo si = GameContent.GetStateInfo((int) code);

                    if (si != null)
                    {
                        if ((si.state_time_type & 4) != 0)
                        {
                            for(int i = 0; i < 3; ++i)
                            {
                                if(remain_time[i] != -1 )
                                {
                                    remain_time[i] -= 6000 * logout_duration;
                                }

                                if(remain_time[i] == 0)
                                {
                                    handle = 0;
                                }
                                else
                                {
                                    handle = m_player.m_hHandle;
                                }
                            }
                        }

                        if (summon != null)
                        {
                            if (enable != 0)
                            {
                                state.SetState(code,summon.m_nCurrentStateUID+1, handle, level,duration,
                                    remain_time, (uint)(remain_fire_time - 100 * si.fire_interval + Globals.GetArTime()),base_damage, state_value, state_string_value);

                                summon.m_vStateList.Add(state);
                            }
                        }
                        else if ( duration[0] != 0 || duration[1] != 0 || duration[2] != 0)
                        {
                            if ( enable == 1 )
                            {
                                state.SetState(code, m_player.m_nCurrentStateUID + 1, handle, level, duration, remain_time,
                                    (uint)(remain_fire_time - 100 * si.fire_interval + Globals.GetArTime()), base_damage, state_value, state_string_value);

                                m_player.m_vStateList.Add(state);
                            }
                            if ( enable == 2 )
                            {
                                state.SetState(code, m_player.m_nCurrentStateUID + 1, handle, level, duration, remain_time,
                                    (uint)(remain_fire_time - 100 * si.fire_interval + Globals.GetArTime()), base_damage, state_value, state_string_value);

                                m_player.m_vStateListRemovedByDeath.Add(state);
                            }
                        }
                    }
                }
            }
            catch (Exception ex) 
            {
                Globals.Log.Error("DB_Login.readStateInfo Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readFavorList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_favor_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    int favor_id = dr.GetInt32(0);
                    int favor = dr.GetInt32(1);

                    m_player.SetFavor(favor_id, favor, false);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readFavorList Exception: {0}", ex);
            }
            conn.Close();
            return true;


        }
        private bool readFriendsList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_friends_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    string friend_id = dr.GetString(0);
                    m_player.m_vFriend.Add(friend_id);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readFriendsList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        } 

        private bool readFriendOfsList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_friendofs_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    string owner_id = dr.GetString(0);
                    m_player.m_vFriendOf.Add(owner_id);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readFriendOfsList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readDenialsList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_denials_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReader datareader = cmd.ExecuteReader();
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(datareader);

                while (dr.Read())
                {
                    string denial_id = dr.GetString(0);
                    m_player.m_vDenial.Add(denial_id);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readDenialsList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readDenialOfsList()
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_denialofs_list";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_ID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    string denial_id = dr.GetString(0);
                    m_player.m_vDenialOf.Add(denial_id);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readDenialOfsList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }
        
        private bool readEquipItemList(DbConnection conn)
        {
            DbCommand cmd = conn.CreateCommand();

            cmd.CommandText = "smp_read_equip_item_list_by_character";
            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_OWNER_UID", DbType.Int32, m_player.m_nUID);

            conn.Open();
            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());

                while (dr.Read())
                {
                    long sid = dr.GetInt64(0);
                    int summon_id = dr.GetInt32(1);
                    int idx = dr.GetInt32(2);
                    int wear_info = dr.GetInt32(2);

                    Creature creature = null;
                    if (summon_id == 0)
                    {
                        creature = m_player;
                    }
                    else
                    {
                        creature = m_player.GetSummon(summon_id);
                    }

                    Item item = m_player.FindItemBySID(sid);
                    List<int> indices = new List<int>();
                    if (item != null && creature != null)
                    {
                        if (creature.m_anWear[wear_info] == null)
                        {
                            indices.Clear();
                            ItemBase.ItemWearType iwt = (ItemBase.ItemWearType) wear_info;
                            if (creature.TranslateWearPosition(ref iwt, item, ref indices))
                            {
                                wear_info = (int)iwt;
                                if (true)// !*(_DWORD *)(v2 + 76) || !((*(_DWORD *)(v2 + 80) - *(_DWORD *)(v2 + 76)) >> 2) )
                                {
                                    creature.m_anWear[wear_info] = item;
                                    item.m_Instance.nWearInfo = (ItemBase.ItemWearType)wear_info;
                                    item.m_bIsNeedUpdateToDB = true;
                                    m_player.m_Inventory.m_fWeightModifier = m_player.m_Inventory.m_fWeightModifier - item.GetWeight();
                                    if (creature.IsPlayer() && wear_info == 1 && item.m_pItemBase.nGroup == 1)
                                        creature.m_StatusFlag |= Creature.StatusFlags.UsingDoubleWeapon;
                                    if (creature.IsSummon())
                                    {
                                        item.m_Instance.OwnSummonHandle = creature.GetHandle();
                                        item.m_Instance.nOwnSummonUID = (int)creature.GetSID();
                                    }
                                    item.m_hBindedTarget = creature.GetHandle();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readEquipItemList Exception: {0}", ex);
            }
            conn.Close();
            return true;
        }

        private bool readCreatureSkillList(Creature creature)
        {
            DbConnection conn = GameDBManager.Instance.CreateConnection();
            DbCommand cmd = conn.CreateCommand();
            int sid = 0;

            if (creature.IsPlayer())
            {
                cmd.CommandText = "smp_read_player_skill_list";
                Player p = creature as Player;
                sid = (int)p.m_nUID;
            }
            else
            {
                cmd.CommandText = "smp_read_summon_skill_list";
                Summon s = (Summon) creature;
                sid = s.m_nSID;
            }

            cmd.CommandType = CommandType.StoredProcedure;

            DbParameter in_sid = GameDBManager.Instance.CreateInParameter(cmd, "IN_SID", DbType.Int32, sid);
            conn.Open();
            cmd.Prepare();

            try
            {
                DbDataReaderTypeCastHelper dr = new DbDataReaderTypeCastHelper(cmd.ExecuteReader());
                while (dr.Read())
                {
                    int skill_uid = dr.GetInt32((int)0);
                    int skill_id = dr.GetInt32((int)1);
                    int skill_level = dr.GetInt32((int)2);
                    uint cool_time = (uint) dr.GetInt32((int)3);
                    creature.SetSkill(skill_uid, skill_id, skill_level, cool_time);
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error("DB_Login.readCreatureSkillList Exception: {0}", ex);
            }
            conn.Close();



            if (creature.IsPlayer())
            {
                creature.SetSkill(-1, 6001, 20, 0);
                creature.SetSkill(-1, 6002, 20, 0);
                creature.SetSkill(-1, 6003, 20, 0);
                creature.SetSkill(-1, 6004, 20, 0);
                creature.SetSkill(-1, 6005, 20, 0);
                creature.SetSkill(-1, 6006, 20, 0);
                creature.SetSkill(-1, 6007, 20, 0);
                creature.SetSkill(-1, 6008, 20, 0);
                creature.SetSkill(-1, 6009, 20, 0);
//                creature.SetSkill(-1, 6010, 20, 0);
                creature.SetSkill(-1, 6013, 20, 0);
                creature.SetSkill(-1, 6014, 20, 0);
                creature.SetSkill(-1, 6015, 20, 0);
                creature.SetSkill(-1, 6016, 20, 0);
                creature.SetSkill(-1, 6017, 20, 0);
                creature.SetSkill(-1, 6018, 20, 0);
                creature.SetSkill(-1, 6019, 20, 0);
                creature.SetSkill(-1, 6020, 20, 0);
                creature.SetSkill(-1, 6021, 20, 0);
                creature.SetSkill(-1, 64809, 20, 0);
                creature.SetSkill(-1, 64810, 20, 0);
                creature.SetSkill(-2, 6901, 20, 0);
                creature.SetSkill(-2, 6902, 20, 0);
                creature.SetSkill(-2, 6903, 20, 0);
                creature.SetSkill(-2, 6904, 20, 0);
                creature.SetSkill(-2, 6905, 20, 0);
                creature.SetSkill(-2, 6906, 20, 0);
                creature.SetSkill(-2, 6909, 20, 0);
                creature.SetSkill(-2, 64806, 20, 0);
                creature.SetSkill(-2, 64807, 20, 0);
                creature.SetSkill(-1, 6022, 20, 0);
                creature.SetSkill(-1, 6023, 20, 0);
                creature.SetSkill(-1, 6024, 20, 0);
                creature.SetSkill(-1, 6025, 20, 0);
                creature.SetSkill(-1, 6026, 20, 0);
                creature.SetSkill(-1, 6027, 20, 0);
                creature.SetSkill(-1, 6028, 20, 0);
                creature.SetSkill(-1, 6029, 20, 0);
                creature.SetSkill(-1, 6030, 20, 0);
                creature.SetSkill(-1, 6031, 20, 0);
                creature.SetSkill(-1, 6032, 20, 0);
                creature.SetSkill(-1, 6033, 20, 0);
                creature.SetSkill(-1, 6034, 20, 0);
                creature.SetSkill(-1, 6035, 20, 0);
                creature.SetSkill(-1, 6036, 20, 0);
                creature.SetSkill(-1, 6037, 20, 0);
                creature.SetSkill(-1, 6038, 20, 0);
                creature.SetSkill(-1, 6039, 20, 0);
                creature.SetSkill(-1, 6040, 20, 0);
                creature.SetSkill(-1, 6041, 20, 0);
                creature.SetSkill(-1, 6042, 20, 0);
                creature.SetSkill(-1, 6043, 20, 0);
                creature.SetSkill(-1, 6044, 20, 0);
                creature.SetSkill(-1, 6045, 20, 0);
                creature.SetSkill(-1, 6046, 20, 0);
                creature.SetSkill(-1, 6047, 20, 0);
                creature.SetSkill(-1, 6048, 20, 0);
                creature.SetSkill(-1, 6049, 20, 0);
                creature.SetSkill(-1, 6061, 20, 0);
                creature.SetSkill(-1, 6062, 20, 0);
                creature.SetSkill(-1, 6063, 20, 0);
                creature.SetSkill(-1, 6064, 20, 0);
                creature.SetSkill(-1, 6065, 20, 0);
                creature.SetSkill(-1, 6066, 20, 0);
                creature.SetSkill(-1, 6067, 20, 0);
                creature.SetSkill(-1, 6068, 20, 0);
                creature.SetSkill(-1, 6069, 20, 0);
                creature.SetSkill(-1, 6070, 20, 0);
                creature.SetSkill(-1, 6071, 20, 0);
                creature.SetSkill(-1, 6072, 20, 0);
                creature.SetSkill(-1, 10009, 20, 0);
                creature.SetSkill(-1, 10010, 20, 0);
                creature.SetSkill(-1, 64808, 20, 0);
                creature.SetSkill(-1, 64813, 20, 0);
                creature.SetSkill(-1, 64814, 20, 0);
                creature.SetSkill(-1, 65061, 20, 0);
                creature.SetSkill(-1, 65062, 20, 0);
            }
            return true;
        }

        bool setBeltSlotInfo()
        {
            for (int i = 0; i < 6; ++i)
            {
                if (beltSlot[i] != 0)
                {
                    Item item = m_player.FindItemBySID(beltSlot[i]);
                    if (item != null)
                        m_player.PutOnBelt(i, item);
                }
            }
            return true;
        }
    }

}
